package pearson.automation.forms;

import junit.framework.Assert;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebElement;

import pearson.automation.forms.courseDetails.CourseForm;
import pearson.automation.forms.courseDetails.CourseTemplates;
import pearson.automation.forms.courseDetails.CourseTemplates.COURSE_TEMPLATES;
import pearson.automation.forms.upload.UploadForm;

import framework.BaseForm;
import framework.elements.Button;
import framework.elements.Label;
import framework.elements.TextBox;

public class BaseFormWithSidebars extends BaseForm {

    private final Button browse = new Button(By.linkText("Browse"), "Browse");
    public final Button myLibrary = new Button(By.linkText("My Library"), "My Library");
    private final Button activityStream = new Button(By.linkText("Activity Stream"), "Activity Stream");
    private final Button newCourse = new Button(By.linkText("New Course"), "New Course");
    private final Button upload = new Button(By.linkText("Upload"), "Upload");
    private final Button home = new Button(By.linkText("Pearson"), "Home");
    private final Button newButton = new Button(By.linkText("New"), "New");
    private final Button edit = new Button(By.linkText("Edit"), "Edit");
    private final Button done = new Button(By.linkText("Done"), "Done");
    private final Button myCourses = new Button(By.cssSelector("li > a[title='View my courses']"), "My courses");
    private final Button myCoursesToggler = new Button(By.xpath("//li[contains(.,'My Courses')]"), "My courses toggler");
    private final Label courseList = new Label(By.id("courses-list"), "courses list");
    private final String coursesCss = "ul#courses-list > li[data-course-ref] > a > span[data-editable-ref]";
    private final String courseXPathTemplate = "//ul[@id='courses-list']/li[@data-course-ref]//span[contains(.,'%1$s')]";
    private final String deleteXPathTemplate = "//ul[@id='courses-list']/li[@data-course-ref][contains(.,'%1$s')]//a[@class='delete']";
    private final String deleteConfirmXPathTemplate = "//ul[@id='courses-list']/li[@data-course-ref][contains(.,'%1$s')]//a[text()='Delete']";
    private final String duplicateXPathTemplate = "//ul[@id='courses-list']/li[@data-course-ref][contains(.,'%1$s')]//a[@class='duplicate']";
    private final String courseByIndexXPathTemplate = "(//ul[@id='courses-list']/li[@data-course-ref]//span[@data-editable-ref])[%1$d]";
    private final Button toggle = new Button(By.cssSelector("a[title='Toggle navigation']"), "Toggle navigation");
    
    protected final TextBox courseEditInPlace = new TextBox(By.className("edit-in-place"), "Editor");

    private Button help = new Button(By.linkText("Help"), "Help");
    private Button chat = new Button(By.linkText("Chat"), "Chat");

    public BaseFormWithSidebars(By titleLocator, String title) {
    super(titleLocator, title);
    browse.assertIsPresent();
    myLibrary.assertIsPresent();
    //newCourse.assertIsPresent();
    //upload.assertIsPresent();
    //home.assertIsPresent();
    }

    public BrowseForm clickBrowse() {
    if (toggle.isPresent()) {
        toggle.clickAndWait();
    }
    browse.clickAndWait();
    return new BrowseForm();
    }

    public StartForm clickHome() {
    home.clickAndWait();
    return new StartForm();
    }
    
    public ActivityStreamForm clickActivityStream() {
        activityStream.clickAndWait();
        return new ActivityStreamForm();
    }
    
    
    
    public CourseForm openCourse(String courseName) {
    Button course = new Button(By.xpath(
            String.format(courseXPathTemplate, courseName)), courseName);
    myCourses.click();
    courseListCollapse(false);
    course.clickAndWait();
    return new CourseForm();
    }
    
    public Button getCourseElement(String courseName) {
        return new Button(By.xpath(
                String.format(courseXPathTemplate, courseName)), courseName);
    }
    
    public void renameCourse(String from, String to) {
        edit.clickAndWait();
        getCourseElement(from).click();
        //Input new name in the textbox
        courseEditInPlace.setText(to);
        courseEditInPlace.getElement().sendKeys(Keys.ENTER);
        done.clickAndWait();
    }
    
    public void deleteCourse(String courseName) {
        edit.clickAndWait();
        Button delete = new Button(By.xpath(
                String.format(deleteXPathTemplate, courseName)), 
                    "Delete button");
        delete.clickAndWait();
        Button deleteConfirm = new Button(By.xpath(
                String.format(deleteConfirmXPathTemplate, courseName)), 
                    "Delete confirmation");
        deleteConfirm.clickAndWait();
        // Pause here
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (done.isPresent()){
            done.clickAndWait();
        }
    }
    
    public void duplicateCourse(String courseName) {
        edit.clickAndWait();
        Button duplicate = new Button(By.xpath(
                String.format(duplicateXPathTemplate, courseName)), 
                    courseName); 
        duplicate.clickAndWait();
        done.clickAndWait();
    }

    public CourseForm createCourse(COURSE_TEMPLATES template) {
    newButton.clickAndWait();
    //Waiting for rendering
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
    }
    newCourse.clickAndWait();
    CourseTemplates templates = new CourseTemplates();
    templates.selectTemplate(template);
    return new CourseForm();
    }

    public HelpForm clickHelp() {
    help.clickAndWait();
    return new HelpForm();
    }

    public void clickChat() {
    chat.click();
    }

    public UploadForm clickUpload() {
    newButton.clickAndWait();
    upload.clickAndWait();
    return new UploadForm();
    }

    public MyLibraryForm clickMyLibrary() {
    myLibrary.clickAndWait();
    return new MyLibraryForm();
    }
    
    public RemoteWebElement getMyLibraryElement() {
    return myLibrary.getElement();
    }
    
    public RemoteWebElement getMyCoursesElement() {
    return this.myCourses.getElement();
    }

    /**
     * Method to collapse\expand course list
     * 
     * @param collapsed
     *            - param set whether list is collapsed or expanded (true -
     *            collapsed, false - expanded)
     */
    public void courseListCollapse(boolean collapsed) {
    for (int i = 0; i < 3; i++) {
        if (myCoursesToggler.getElement().getAttribute("class").equals("collapsed") != collapsed) {
        myCourses.click();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        }
    }
    Assert.assertSame("Course list is in a wrong state", myCoursesToggler.getElement().getAttribute("class").equals("collapsed"), collapsed);
    }

    public String[] getCourseNames() {
    courseListCollapse(false);
    courseList.waitAndAssertIsPresent();
    Object[] courses = browser.getDriver().findElements(By.cssSelector(coursesCss)).toArray();
    String[] res = new String[courses.length];
    for (int i = 0; i < courses.length; i++) {
        try {
        res[i] = ((WebElement) courses[i]).getText();
        } catch (Exception e) {
        fatal("Getting course list fails");
        }
    }
    return res;
    }
    
    public String getCourseName(int index) {
        return browser.getDriver().findElementByXPath(String.format(courseByIndexXPathTemplate, index)).getText();
    }
}
